#include "StdAfx.h"
#include "GlobalVariable.h"

CGlobalVariable::CGlobalVariable(void)
{
	m_start = false;
}

CGlobalVariable::~CGlobalVariable(void)
{
}


unsigned int CGlobalVariable::g_u32_SecurityAlgorithm(BYTE w_seed[],BYTE SECURITYCONSTANT[])
{
	BYTE   Seed[4], AppKeyConst[4], Key[4];
	unsigned int  uint32_key;

	Seed[0] = w_seed[0];
	Seed[1] = w_seed[1];
	Seed[2] = w_seed[2];
	Seed[3] = w_seed[3];

	AppKeyConst[0] = SECURITYCONSTANT[0];
	AppKeyConst[1] = SECURITYCONSTANT[1];
	AppKeyConst[2] = SECURITYCONSTANT[2];
	AppKeyConst[3] = SECURITYCONSTANT[3];

	Key[0] = (Seed[0] ^ AppKeyConst [0]) + (Seed[1] ^ AppKeyConst [0]);
	Key[1] = (Seed[1] ^ AppKeyConst [1]) + (Seed[0] ^ AppKeyConst [1]);
	Key[2] = (Seed[2] ^ AppKeyConst [2]) + (Seed[3] ^ AppKeyConst [2]);
	Key[3] = (Seed[3] ^ AppKeyConst [3]) + (Seed[2] ^ AppKeyConst [3]);

	uint32_key = Key[0] * 16777216 + Key[1] * 65536 + Key[2] * 256  + Key[3] ;

	return   uint32_key;

}

CGlobalVariable  glv;


//==============================================================================
CHex2Bin::CHex2Bin(void)
{
	Fill = 0xff;
	BinLength = 0;;
	cFail = -1;
	InfoString = "";
}
//------------------------------------------------------------------------------
bool __fastcall CHex2Bin::CharToByte(char *pChar, unsigned char *pByte)
{
	unsigned char h,l;
	h = pChar[0];
	l = pChar[1];

	if(l>='0' && l<='9')        l = l - '0';
	else if(l>='a' && l<='f')   l = l - 'a' + 0xa;
	else if(l>='A' && l<='F')   l = l - 'A' + 0xa;
	else    return false;

	if(h>='0' && h<='9')        h = h - '0';
	else if(h>='a' && h<='f')   h = h - 'a' + 0xa;
	else if(h>='A' &&h <='F')   h = h - 'A' + 0xa;
	else    return false;

	*pByte = (h<<4) + l;
	return true;
}

//------------------------------------------------------------------------------
//     * 00 - Data record
//     * 01 - End of file record
//     * 02 - Extended segment address record
//     * 03 - Start segment address record
//     * 04 - Extended linear address record
//     * 05 - Start linear address record
//------------------------------------------------------------------------------

int __fastcall CHex2Bin::Convert(char *sfile, unsigned char **dbuf, unsigned int *Length, unsigned int * BeginAddr)
{
	unsigned int i;
	CFile        sourceFile, destFile;
	CString      pBuffer;
	char        *cBuffer;

	unsigned int     Begin_addr_line;
	unsigned int     Max_addr_line = 0;
	unsigned int     Min_addr_line = 0xffffffff;
	bool             SkipLine = 0;

	unsigned int     Now_addr = 0;
	unsigned int     start_addr = 0, end_addr = 0;

	unsigned char    Now_len;
	unsigned char    len;
	unsigned char    addr1, addr2, addr3, addr4;
	unsigned char    sum, rbyte;

	unsigned int     nEnd, n, bin_length;
	int  fail = 0;

	try{
		sourceFile.Open(sfile,CFile::modeRead);
		cBuffer = new char[sourceFile.GetLength()];
		sourceFile.Read(cBuffer,sourceFile.GetLength());
		sourceFile.Close();
	}catch(...){
		fail = 1;
	}

	pBuffer = cBuffer;

	nEnd = pBuffer.Find(":00000001FF");
	if(nEnd == 0) fail = 2;                                                     // find file end
	nEnd--;

	bin_length=0;
	n = 0;
	while(n < nEnd){
		if(fail) break;

		if(cBuffer[n] == ':'){

			CharToByte(&cBuffer[n+1], &len);
			CharToByte(&cBuffer[n+3], &addr1);
			CharToByte(&cBuffer[n+5], &addr2);
			start_addr = (addr1<<8) + addr2;

			//-----checksum  start
			sum = 0;
			for(i=0; i<(len+5); i++) {                                      //5: length,addr1,addr2,label,checksum
				CharToByte(&cBuffer[n+1+(i*2)], &rbyte);
				sum += rbyte;
			}
			if(sum != 0) fail = 3;
			//-----checksum  end 

			switch(cBuffer[n+8]){
			case '0':        
				//Data record
				start_addr += Begin_addr_line;
				end_addr = start_addr + len;
				if (start_addr < Min_addr_line )
				{
					Min_addr_line = start_addr;
				}
				if (end_addr > Max_addr_line)
				{
					Max_addr_line = end_addr-1;
				}
				break;

			case '1':                                               //End of file record
				fail = 4;
				break;

			case '2':                                               //Extended segment address record
				fail = 9;
				break;

			case '4':                                               //Extended linear address record
				CharToByte(&cBuffer[n+9],  &addr1);
				CharToByte(&cBuffer[n+11], &addr2);
				Begin_addr_line  = ((addr1<<8)+addr2) << 16;
				break;

			case '3':                                               //Start segment address record
				fail = 9;
				break;

			case '5':                                               //Start linear address record
				fail = 9;
				break;

			default:
				fail = 4;
				break;
			}

			n += len*2 + 11;
		}else{
			n++;
		}
	}

	if(fail == 0){

		if (Min_addr_line < Max_addr_line)
		{
			bin_length = Max_addr_line - Min_addr_line + 1;
		}

		this->BinLength  =  bin_length;

		*dbuf = new unsigned char [bin_length];

		memset(*dbuf,Fill,bin_length);

		n = 0;
		while(n < nEnd){

			if(fail) break;

			if(cBuffer[n] == ':'){

				CharToByte(&cBuffer[n+1], &len);
				CharToByte(&cBuffer[n+3], &addr1);
				CharToByte(&cBuffer[n+5], &addr2);
				start_addr = (addr1<<8) + addr2;

				switch(cBuffer[n+8]){
				case '0':                                               //Data record
					start_addr += Now_addr;
					for(i=0; i<len; i++){
						CharToByte(&cBuffer[n + 9 + (i*2)], &rbyte);
						(*dbuf)[start_addr - Min_addr_line + i]  = rbyte;
						//??? Begin_addr_seg  Begin_addr_line
					}
					break;

				case '1':                                               //End of file record
					fail = 4;
					break;

				case '2':   
					break;
				case '4':                                               //Extended linear address record
					CharToByte(&cBuffer[n+9],  &addr1);
					CharToByte(&cBuffer[n+11], &addr2);
					Now_addr  = ((addr1<<8)+addr2) << 16;
					break;
				case '3':                                               //Start segment address record
					break;
				case '5':                                               //Start linear address record
					break;

				default:
					fail = 4;
					break;
				}

				n += len*2+11;
			}else{
				n++;
			}
		}
	}

	delete [] cBuffer;

	if(Length != NULL){
		*Length = bin_length;                                                   // return true file length
	}
	if (BeginAddr != NULL)
	{
		*BeginAddr = Min_addr_line;
	}


	switch (fail){
	case 0: InfoString = "Success.";                    break;
	case 1: InfoString = "Open hex file error.";        break;
	case 2: InfoString = "Hex file eof error.";         break;
	case 3: InfoString = "Hex file checksum error.";    break;
	case 4: InfoString = "Hex file wrong label.";       break;
	case 5: InfoString = "Write Dest file error.";      break;
	case 6: InfoString = "Dest buffer overflow.";       break;
	case 7: InfoString = "Length parameter can not be NULL"; break;
	case 8: InfoString = "Get bin length Success.";     break;                  // only when (dfile == NULL) && (dbuf == NULL) 
	default:InfoString = "Unknow error.";               break;
	}

	this->cFail = fail;
	return fail;
}


DWORD __fastcall CHex2Bin::CStringIDToDword(CString csID)
{
	unsigned char  btemp;
	char *   ctemp = csID.GetBuffer();
	DWORD    dtemp = 0;
	csID.ReleaseBuffer();

	for (int n = 0; n<100 ;n++ )
	{
		btemp = *(ctemp+n);
		if (btemp == '\0')
		{
			break;
		}
		if(btemp>='0' && btemp<='9')        dtemp = btemp - '0' + dtemp*16;
		else if(btemp>='a' && btemp<='f')   dtemp = btemp - 'a' + 0xa + dtemp*16;
		else if(btemp>='A' && btemp<='F')   dtemp = btemp - 'A' + 0xa + dtemp*16;
		else    return false;
	}

	return dtemp;


}